package com.ruoyi.SSL.controller;

import java.util.List;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.SSL.domain.SslDomain;
import com.ruoyi.SSL.service.ISslDomainService;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.SSL.domain.SslApply;
import com.ruoyi.SSL.service.ISslApplyService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 证书申请Controller
 *
 * @author ruoyi
 * @date 2024-09-07
 */
@Controller
@RequestMapping("/SSL/apply")
public class SslApplyController extends BaseController
{
    private String prefix = "SSL/apply";

    @Autowired
    private ISslApplyService sslApplyService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private ISslDomainService domainService;

    @RequiresPermissions("SSL:apply:view")
    @GetMapping()
    public String apply()
    {
        return prefix + "/apply";
    }

    /**
     * 查询证书申请列表
     */
    @RequiresPermissions("SSL:apply:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(SslApply sslApply)
    {
        startPage();
        List<SslApply> list = sslApplyService.selectSslApplyList(sslApply);
        return getDataTable(list);
    }

    /**
     * 导出证书申请列表
     */
    @RequiresPermissions("SSL:apply:export")
    @Log(title = "证书申请", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SslApply sslApply)
    {
        List<SslApply> list = sslApplyService.selectSslApplyList(sslApply);
        ExcelUtil<SslApply> util = new ExcelUtil<SslApply>(SslApply.class);
        return util.exportExcel(list, "证书申请数据");
    }

    /**
     * 新增证书申请
     */
    @GetMapping("/add")
    public String add(ModelMap modelMap)
    {
        //判断是否已经配置了请求appId和秘钥
        String appId = configService.selectConfigByKey("api.appId");
        String appSecret = configService.selectConfigByKey("api.appSecret");
        if(StringUtils.isBlank(appId) || StringUtils.isBlank(appSecret)){
            throw new RuntimeException("平台公用参数配置有误！");
        }
        AjaxResult aj = configService.getPlatformInfoByAppId(CommUtils.REQ_API_URI, appId, appSecret);
        if(aj.isSuccess()){
            modelMap.put("platFormInfo", JSONUtil.parseObj("data"));
        }else{
            modelMap.put("platFormInfo", null);
            modelMap.put("error", aj.get("msg").toString());
        }
        return prefix + "/add";
    }

    /**
     * 新增保存证书申请
     */
    @RequiresPermissions("SSL:apply:add")
    @Log(title = "证书申请", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(SslApply sslApply)
    {
        //判断是否已经配置了请求appId和秘钥
        String appId = configService.selectConfigByKey("api.appId");
        String appSecret = configService.selectConfigByKey("api.appSecret");
        if(StringUtils.isBlank(appId) || StringUtils.isBlank(appSecret)){
            return AjaxResult.error("平台公用参数配置有误！");
        }
//        return sslApplyService.insertSslApply(sslApply);
        return AjaxResult.error("1");
    }

    @RequiresPermissions("SSL:apply:authorizations")
    @GetMapping("/authorizations/{id}")
    public String authorizations(@PathVariable("id") Long id, ModelMap mmap){
        SslApply sslApply = sslApplyService.selectSslApplyById(id);
        mmap.put("sslApply", sslApply);
        Object authInfoObj = CacheUtils.get(sslApply.getCertificateDomain()+"_authInfo");
        if(authInfoObj == null || StringUtils.isEmpty(authInfoObj.toString())){
            AjaxResult aj = sslApplyService.getAuthorizationsInfo(sslApply);
            if(!aj.isSuccess()){
                mmap.put("msg", aj.get("msg"));
                authInfoObj = null;
            }else{
                CacheUtils.put(sslApply.getCertificateDomain()+"_authInfo", aj.get("data"));
                authInfoObj = aj.get("data");
            }
        }
        mmap.put("authJson", authInfoObj);
        return prefix + "/authorizations";
    }

    @ResponseBody
    @GetMapping("/authz/{id}")
    public AjaxResult authz(@PathVariable("id") Long id){
        SslApply sslApply = sslApplyService.selectSslApplyById(id);
        Object authInfoObj = CacheUtils.get(sslApply.getCertificateDomain()+"_authInfo");
        if(authInfoObj == null || StringUtils.isEmpty(authInfoObj.toString())){
            return AjaxResult.error("域名验证授权信息为空！");
        }
        //判断域名Txt记录值是否生效
        JSONObject authInfoJson = JSONUtil.parseObj(authInfoObj);
        String suffix = StringUtils.getDomainSuffix(sslApply.getCertificateDomain());
        if(StringUtils.isBlank(suffix)){
            return AjaxResult.error("域名参数错误！");
        }
        AjaxResult aj = CommUtils.isHasAuthInfo(authInfoJson.getStr("domainName")+suffix, authInfoJson.getStr("keyAuthorization"));
        if(aj.isSuccess()){
            aj = sslApplyService.authStatus(sslApply, 0);
            if(aj.isSuccess()){
                SslDomain sslDomain = domainService.getByDomain(sslApply);
                sslDomain.setStatus("1");
                domainService.updateSslDomain(sslDomain);
                sslApply.setStatus("1");
                sslApplyService.updateSslApply(sslApply);
            }
            return aj;
        }else{
            return AjaxResult.error("dns记录未添加或未生效，一般生效时间为10分钟！");
        }
    }

    @PostMapping("/downCertificate/{id}")
    @ResponseBody
    public AjaxResult downCertificate(@PathVariable("id") Long id)
    {
        SslApply sslApply = sslApplyService.selectSslApplyById(id);
        AjaxResult aj = sslApplyService.downCertificate(sslApply);
        if(aj.isSuccess()){
            SslDomain sslDomain = domainService.getByDomain(sslApply);
            if(!StringUtils.equals("Y", sslDomain.getIsYzOver())){
                sslDomain.setIsYzOver("Y");
            }
            sslDomain.setStatus("2");
            domainService.updateSslDomain(sslDomain);
            sslApply.setStatus("2");
            sslApplyService.updateSslApply(sslApply);
        }
        return aj;
    }


    @GetMapping("/downFilePage/{id}")
    public String downFilePage(@PathVariable("id") Long id, ModelMap mmap){
        SslApply sslApply = sslApplyService.selectSslApplyById(id);
        if(StringUtils.isBlank(sslApply.getSslFilePath())){
            //发起pem文件内容请求
            AjaxResult aj = sslApplyService.getSSLInfo(sslApply);
            if(aj.isSuccess()){
                JSONObject sslJson = JSONUtil.parseObj(aj.get("data"));
                String sslPemFilePath = FileUtils.writeTxtInFile(sslJson.getStr("sslPemContent"), sslApply.getCertificateDomain()+".pem");
                String sslKeyFilePath = FileUtils.writeTxtInFile(sslJson.getStr("sslKeyContent"), sslApply.getCertificateDomain()+".key");
                sslApply.setSslFilePath(sslKeyFilePath+","+sslPemFilePath);
                //更新数据
                sslApplyService.updateSslApply(sslApply);
                mmap.put("sslPemContent", sslJson.getStr("sslPemContent"));
                mmap.put("sslKeyContent", sslJson.getStr("sslKeyContent"));
            }
        }else{
            //重新计算信息  读取文件数据
            String[] fileArray = sslApply.getSslFilePath().split(",");
            mmap.put("sslKeyContent", FileUtils.readFileContent(fileArray[0]));
            mmap.put("sslPemContent", FileUtils.readFileContent(fileArray[1]));
        }
        mmap.put("sslApply", sslApply);
        return prefix + "/downFilePage";
    }


    @ResponseBody
    @GetMapping("/renewalInfo/{id}")
    public AjaxResult renewalInfo(@PathVariable("id") Long id){
        SslApply sslApply = sslApplyService.selectSslApplyById(id);
        return AjaxResult.error("");
    }

    /**
     * 修改证书申请
     */
    @RequiresPermissions("SSL:apply:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        SslApply sslApply = sslApplyService.selectSslApplyById(id);
        mmap.put("sslApply", sslApply);
        return prefix + "/edit";
    }

    /**
     * 修改保存证书申请
     */
    @RequiresPermissions("SSL:apply:edit")
    @Log(title = "证书申请", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(SslApply sslApply)
    {
        return toAjax(sslApplyService.updateSslApply(sslApply));
    }

    /**
     * 删除证书申请
     */
    @RequiresPermissions("SSL:apply:remove")
    @Log(title = "证书申请", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(sslApplyService.deleteSslApplyByIds(ids));
    }

}
